package com.mygame.center;

import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.ConsulRawClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.health.model.HealthService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 自定义的consul范围注册
 */
public class CustomConsulClient implements DiscoveryClient {


    private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class);
    public ConsulClient client;
    public ConsulDiscoveryProperties properties;

    public void init() {

    }

    public CustomConsulClient(ConsulClient client, ConsulDiscoveryProperties properties) {
        ConsulRawClient rawClient = new ConsulRawClient();
        this.client = new ConsulClient(rawClient);
        this.properties = properties;
    }

    public String description() {
        return "Spring Cloud Consul Discovery Client";
    }

    public List<ServiceInstance> getInstances(final String serviceId) {
        return this.getInstances(serviceId, QueryParams.DEFAULT);
    }

    public List<ServiceInstance> getInstances(final String serviceId, final QueryParams queryParams) {
        List<ServiceInstance> instances = new ArrayList();
        this.addInstancesToList(instances, serviceId, queryParams);
        return instances;
    }


    private void addInstancesToList(List<ServiceInstance> instances, String serviceId, QueryParams queryParams) {
        String aclToken = this.properties.getAclToken();
        Response services;
        if (StringUtils.hasText(aclToken)) {
            services = this.client.getHealthServices(serviceId, this.properties.getDefaultQueryTag(), this.properties.isQueryPassing(), queryParams, aclToken);
        } else {
            services = this.client.getHealthServices(serviceId, this.properties.getDefaultQueryTag(), this.properties.isQueryPassing(), queryParams);
        }


        Iterator iterator = ((List) services.getValue()).iterator();
        while (iterator.hasNext()) {
            HealthService service = (HealthService) iterator.next();
            String host = ConsulServerUtils.findHost(service);
            Map<String, String> metadata = service.getService().getMeta();
            String instanceId = properties.getInstanceId();
            boolean secure = false;
            if (metadata.containsKey("secure")) {
                secure = Boolean.parseBoolean((String) metadata.get("secure"));
            }
            instances.add(new DefaultServiceInstance(instanceId, serviceId, host, service.getService().getPort(), false, metadata));
        }

    }

    public List<ServiceInstance> getAllInstances() {
        List<ServiceInstance> instances = new ArrayList();
        Response<Map<String, List<String>>> services = this.client.getCatalogServices(QueryParams.DEFAULT);
        Iterator var3 = ((Map) services.getValue()).keySet().iterator();

        while (var3.hasNext()) {
            String serviceId = (String) var3.next();
            this.addInstancesToList(instances, serviceId, QueryParams.DEFAULT);
        }

        return instances;
    }

    public List<String> getServices() {
        String aclToken = this.properties.getAclToken();
        return StringUtils.hasText(aclToken) ? new ArrayList(((Map) this.client.getCatalogServices(QueryParams.DEFAULT, aclToken).getValue()).keySet()) : new ArrayList(((Map) this.client.getCatalogServices(QueryParams.DEFAULT).getValue()).keySet());
    }


    /**
     * @deprecated
     */
    @Deprecated
    public interface LocalResolver {
        String getInstanceId();

        Integer getPort();
    }
}
